﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.ETL
{
    /// <summary>
    /// 
    /// </summary>
    public partial class TablePartitionEditor : Form, IComponentEditor
    {
        private object _ActivityNode;
        private TablePartitionComponent _Partitioner;

        /// <summary>
        /// 
        /// </summary>
        public TablePartitionEditor()
        {
            InitializeComponent();
        }

        private void btn_Refresh_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txt_ConnStr.Text))
            {
                string connStr = this.txt_ConnStr.Text;
                string schemaName = "dbo";
                if(!string.IsNullOrEmpty(this.txt_Schema.Text))
                    schemaName = this.txt_Schema.Text;
                this.PopulateTables(connStr, schemaName);
            }
        }

        #region Implementation of IComponentEditor

        public event UpdateComponentSettings UpdateComponentSettingEvent;

        /// <summary></summary>
        public object OwnerActivityNode
        {
            get { return _ActivityNode; }
            set { _ActivityNode=value; }
        }

        /// <summary></summary>
        public Type WorkflowComponentType
        {
            get { return typeof (TablePartitionComponent); }
        }

        /// <summary></summary>
        public void LoadSettings(GlobalVariable[] globalVars, WorkflowComponentBase[] fromComponents, object activityNode, WorkflowComponentBase wfComponent)
        {
            this._ActivityNode = activityNode;
            this._Partitioner = (TablePartitionComponent) wfComponent;

            TablePartitionInstruction instruction = (TablePartitionInstruction) this._Partitioner.Instruction;
            this.txt_ConnStr.Text = instruction.ConnStr;
            this.txt_Schema.Text = instruction.SchemaName;
            this.PopulateTables(instruction.ConnStr, instruction.SchemaName);
            this.SelectComboxValue(this.cbo_Tables, instruction.TblName);
            this.PopulateTableFields(instruction.ConnStr, instruction.SchemaName, instruction.TblName);
            if(instruction.PartitionFields !=null && instruction.PartitionFields.Count>0)
            {
                foreach(string fieldName in instruction.PartitionFields)
                {
                    this.lb_PartitionFields.Items.Add(fieldName);
                }
            }
            this.ck_GroupByValue.Checked = instruction.GroupByFieldValue;
            this.txt_Prefix.Text = instruction.OutputTablePrefix;
            this.num_Count.Value = instruction.RecordPerTable;
        }

        private void PopulateTableFields(string connStr, string schemaName, string tblName)
        {
            this.clb_PartitionFields.Items.Clear();
            TableColumn[] cols = DbUtil.GetTableColumns(DataProviderType.MSSQL, connStr, schemaName, tblName);
            if(cols !=null && cols.Length>0)
            {
                foreach(TableColumn col in cols)
                {
                    this.clb_PartitionFields.Items.Add(col.ColumnName);
                }
            }
        }

        private void SelectComboxValue(ComboBox comboBox, string value)
        {
            if(comboBox.Items.Count>0 && !string.IsNullOrEmpty(value))
            {
                for(int i=0;i<comboBox.Items.Count;i++)
                {
                    if(comboBox.Items[i].ToString()==value)
                    {
                        comboBox.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

        private void PopulateTables(string connStr, string schemaName)
        {
            this.cbo_Tables.Items.Clear();
            string[] tblNames = DbUtil.GetTableNames(DataProviderType.MSSQL, schemaName, connStr);
            if(tblNames !=null && tblNames.Length>0)
            {
                foreach(string tblName in tblNames)
                {
                    this.cbo_Tables.Items.Add(tblName);
                }
            }
        }

        /// <summary></summary>
        public void SaveSettings()
        {
            TablePartitionInstruction instruction = (TablePartitionInstruction) this._Partitioner.Instruction;
            instruction.ConnStr = this.txt_ConnStr.Text;
            instruction.SchemaName = this.txt_Schema.Text;
            instruction.TblName = this.cbo_Tables.Text;
            instruction.PartitionFields=new List<string>();
            for(int i=0;i<this.lb_PartitionFields.Items.Count;i++)
            {
                instruction.PartitionFields.Add(this.lb_PartitionFields.Items[i].ToString());
            }
            instruction.GroupByFieldValue = this.ck_GroupByValue.Checked;
            instruction.OutputTablePrefix = this.txt_Prefix.Text;
            instruction.RecordPerTable = (int) this.num_Count.Value;
            this._Partitioner.Instruction = instruction;
        }

        /// <summary></summary>
        public TestResult Test()
        {
            throw new NotImplementedException("");
        }

        #endregion

        private void btn_OK_Click(object sender, EventArgs e)
        {
            this.SaveSettings();
            if (this.UpdateComponentSettingEvent != null)
                this.UpdateComponentSettingEvent(this._ActivityNode, this._Partitioner);
            this.Close();
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void cbo_Tables_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_Tables.SelectedIndex>=0 && !string.IsNullOrEmpty(this.txt_ConnStr.Text))
            {
                this.PopulateTableFields(this.txt_ConnStr.Text,this.txt_Schema.Text,this.cbo_Tables.Text);
            }
        }

        private void btn_AddField_Click(object sender, EventArgs e)
        {
            for(int i=0;i<this.clb_PartitionFields.Items.Count;i++)
            {
                if (this.clb_PartitionFields.GetItemChecked(i))
                    this.lb_PartitionFields.Items.Add(this.clb_PartitionFields.Items[i].ToString());
            }
        }

        private void btn_RemovePartitionField_Click(object sender, EventArgs e)
        {
            if(this.lb_PartitionFields.SelectedIndex>=0)
            {
                this.lb_PartitionFields.Items.RemoveAt(this.lb_PartitionFields.SelectedIndex);
            }
        }

        private void btn_Up_Click(object sender, EventArgs e)
        {
            if(this.lb_PartitionFields.SelectedIndex>0)
            {
                int idx = this.lb_PartitionFields.SelectedIndex;
                string prevItem = this.lb_PartitionFields.Items[idx - 1].ToString();
                string currentItem = this.lb_PartitionFields.Items[idx].ToString();
                this.lb_PartitionFields.Items[idx - 1] = currentItem;
                this.lb_PartitionFields.Items[idx] = prevItem;
            }
        }

        private void btn_Down_Click(object sender, EventArgs e)
        {
            if (this.lb_PartitionFields.SelectedIndex >= 0 && this.lb_PartitionFields.SelectedIndex < this.lb_PartitionFields.Items.Count -1)
            {
                int idx = this.lb_PartitionFields.SelectedIndex;
                string nextItem = this.lb_PartitionFields.Items[idx + 1].ToString();
                string currentItem = this.lb_PartitionFields.Items[idx].ToString();
                this.lb_PartitionFields.Items[idx + 1] = currentItem;
                this.lb_PartitionFields.Items[idx] = nextItem;
            }
        }
    }
}
